﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using RoboTrocity;
using RoboTrocity.Code.ObjectStates;

namespace RoboTrocity.Code.GameStates {
	class PlayState : GameState {
		private Player playerRef;
		private Map mapRef;
		private Camera cameraRef;

		//needs map, player, camera
		public PlayState(PushState pushState, PopState popState, ref Map map, ref Player player, ref Camera camera)
			: base(pushState, popState) {
			playerRef = player;
			mapRef = map;
			cameraRef = camera;

		}

		public override void ProcessInput(KeyboardState kState, KeyboardState prevKState, MouseState mState, MouseState prevMState) {
			keyState = kState;
			prevKeyState = prevKState;
			mouseState = mState;
			prevMouseState = prevMState;

			if (keyIsPressed(Keys.Escape, false)) {
                playerRef.Position = new Point(10, 10);
			}
			if (keyIsPressed(Keys.Space, false)) {
				playerRef.jump();
			}

			if (keyIsPressed(Keys.D1, false)) {
				playerRef.switchGun(1);
			}
			if (keyIsPressed(Keys.D2, false)) {
				playerRef.switchGun(2);
			}

			if (keyIsPressed(Keys.Up, true)) {
				//get on a ladder
                if (playerRef.CurrentState is ClimbingState)
                {
                    (playerRef.CurrentState as EntityState).MoveUp();
                }
                else
                {
                    GameObject obj = mapRef.getObjectAt(playerRef.Center);
                    if (obj is Ladder)
                    {
                        ((Ladder)obj).PlaceEntityOnLadder(playerRef);
                    }
                }
            }
            else if (keyIsPressed(Keys.Down, true))
            {
                (playerRef.CurrentState as EntityState).MoveDown();
            }
            
			if (keyIsPressed(Keys.Left, true)) {
				playerRef.moveLeft();
			} else if (keyIsPressed(Keys.Right, true)) {
				playerRef.moveRight();
			}

			if (keyIsPressed(Keys.D, true)) {
				cameraRef.moveX(1);
			} else if (keyIsPressed(Keys.A, true)) {
				cameraRef.moveX(-1);
			}

			if (keyIsPressed(Keys.C, false)) {
				cameraRef.isFollowingOrders = !cameraRef.isFollowingOrders;
			}
			if (keyIsPressed(Keys.F, false)) {
				GameObject obj = mapRef.getObjectAt(playerRef.Center);
				if (obj is BinarySwitch) {
					((BinarySwitch)obj).flipSwitch();
				}
			}

			if (keyIsPressed(Keys.A, true)) {
				foreach (Bullet bullet in playerRef.shoot()) {
					mapRef.addObject(bullet);
				}
			}

			//when you first click. Doesn't count holding it down
			if (keyIsPressed(Keys.LeftShift, true)) {
				if (mouseState.LeftButton == ButtonState.Pressed && prevMouseState.LeftButton == ButtonState.Released) {
					Point mousePos = new Point((int)(Mouse.GetState().X + cameraRef.Origin.X),
								(int)(Mouse.GetState().Y + cameraRef.Origin.Y));
					mousePos.X = (mousePos.X / 10) * 10;
					mousePos.Y = (mousePos.Y / 10) * 10;
					Terrain newT = new Terrain(mousePos, "brick");
					mapRef.addObject(newT);
				}
			}

			if (keyIsPressed(Keys.LeftControl, true)) {
				if (mouseState.LeftButton == ButtonState.Pressed && prevMouseState.LeftButton == ButtonState.Released) {
					//delete the selected object from the map
					GameObject objToDel = MapEditor.findSelectedObject(mapRef,
									new Point((int)(Mouse.GetState().X + cameraRef.Origin.X),
											(int)(Mouse.GetState().Y + cameraRef.Origin.Y)));
					if (objToDel != null) {
						mapRef.removeObject(objToDel);
					}
				}
				if (keyIsPressed(Keys.S, false)) {
					Map.saveMap(mapRef);
				}
			}
		}

		public override void Draw(SpriteBatch spriteBatch) {
			foreach (GameObject gObject in mapRef.ObjectList.ObjectArray) {
				gObject.Draw(spriteBatch, cameraRef);
			}

			string mouseWindow = "Window Pos\nX=" + Mouse.GetState().X + "\nY=" + Mouse.GetState().Y;
			string mouseMap = "Map Pos\nX=" + (Mouse.GetState().X + cameraRef.Origin.X) +
							"\nY=" + (Mouse.GetState().Y + cameraRef.Origin.Y);
			string playerPos = "Player Pos\nX=" + playerRef.Position.X + "\nY=" + playerRef.Position.Y;

			SpriteFont font = GraphicsDispenser.GetFont("TestFont");

			spriteBatch.DrawString(font, mouseWindow, new Vector2(650, 50), Color.LightGreen,
							0, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
			spriteBatch.DrawString(font, mouseMap, new Vector2(650, 150), Color.LightGreen,
							0, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
			spriteBatch.DrawString(font, playerPos, new Vector2(650, 250), Color.LightGreen,
							0, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);
		}

		public override void Update(float elapsed) {
			if (cameraRef.isFollowingOrders) {
				cameraRef.centerOnPoint(playerRef.Center);
				cameraRef.Update();
			}
			mapRef.Update(elapsed);
		}
	}
}
